package com.kitty.mina.codec.xf;

import com.kitty.game.utils.ByteBuffUtil;
import com.kitty.game.utils.Const;
import com.kitty.mina.Modules;
import com.kitty.mina.codec.IMessageDecoder;
import com.kitty.mina.codec.SerializerHelper;
import com.kitty.mina.message.Message;
import com.kitty.mina.message.MessageFactory;
import com.kitty.mina.session.SessionManager;
import com.kitty.mina.session.SessionProperties;

import java.net.InetSocketAddress;
import java.util.HashMap;

import lombok.extern.slf4j.Slf4j;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.CumulativeProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;
import org.nutz.json.Json;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 自定义解码器，确保能读到完整的包
 */
@Slf4j
public class WDDecoder extends CumulativeProtocolDecoder {
//    Logger logger = LoggerFactory.getLogger(WDDecoder.class);

    @Override
    protected boolean doDecode(IoSession ioSession, IoBuffer ioBuffer, ProtocolDecoderOutput protocolDecoderOutput) throws Exception {
//        String ipAddr = ((InetSocketAddress)ioSession.getRemoteAddress()).getAddress().getHostAddress();
//        if("0.0.0.0".equals(ipAddr)){
//            log.info("假人接受包，不处理。忽略");
//            return false;
//        }
        // 丢包，断包处理
        if (ioBuffer.remaining() >= 12) {
            ioBuffer.mark();// 标记当前position的快照标记mark，以便后继的reset操作能恢复position位置，开始是0

            //读到包头
            while (true) {
                //不够读meta基础长度就返回
                if (ioBuffer.remaining() < 12) {
                    ioBuffer.reset();
                    return false;
                }

                if (ByteBuffUtil.readUnsignedShort(ioBuffer) == 0x4D5A) {
                    ByteBuffUtil.readUnsignedShort(ioBuffer);
                    break;
                }
            }
            if (ioBuffer.remaining() < 8) {
                ioBuffer.reset();
                return false;
            }

            long time = ByteBuffUtil.readUnsignedInt(ioBuffer);
            int length = ByteBuffUtil.readUnsignedShort(ioBuffer);
            if (ioBuffer.remaining() < length) {
                ioBuffer.reset();
                return false;
            }
           //log.warn("长度足够==协议号==={}={}",length, ioBuffer.getHexDump());
            int moduleId = ioBuffer.getUnsignedShort();//协议号

            Class<?> msgClazz = MessageFactory.INSTANCE.getMessage(moduleId, 0);
            if (msgClazz == null) {
                log.warn("未处理封包==协议号={}={}", moduleId, ioBuffer.getHexDump());
                length = length - 2;
                for (int i = 0; i < length; i++) {
                    ioBuffer.getUnsigned();
                }
                return true;
            }

            HashMap<String, Long> heartbeatMap = SessionManager.INSTANCE.getSessionAttr(ioSession, SessionProperties.HEARTBEAT_MAP, HashMap.class);
            if (heartbeatMap == null) {/**这个应该只有第一次的时候为空*/
                heartbeatMap = new HashMap<>();
            }
            /**如果是心跳包 把心跳时间写进去*/
            if (moduleId == Modules.CMD_ECHO) {
                heartbeatMap.put(Const.LAST_HEART_TIME, time);
            }
            heartbeatMap.put(Const.REQ_CURR_TIME, time);
            ioSession.setAttribute(SessionProperties.HEARTBEAT_MAP, heartbeatMap);

            byte[] body = new byte[length - 2];
            ioBuffer.get(body);
            IMessageDecoder msgDecoder = SerializerHelper.getInstance().getDecoder();
            try {

                Message msg = msgDecoder.readMessage(moduleId, (short) 0, body);
                protocolDecoderOutput.write(msg);
                if (4274 != moduleId && 61634 != moduleId){
                    log.error("解析协议:==={}=={}", moduleId, Json.toJson(msg));
                }
            } catch (Exception e) {
                log.error("解包出错:==={}=={}", moduleId, ioBuffer.getHexDump());
            }

//            if (ioBuffer.remaining() > 0) {
//                if (ioBuffer.getHexDump().startsWith("4D")) {
//                    return true;
//                } else  {
//                    logger.error("数据未解完协议号=={}=={}", moduleId, ioBuffer.getHexDump());
//                    while (!ioBuffer.getHexDump().startsWith("4D 5A")) {
//                        if (ioBuffer.remaining() <= 0) {
//                            return true;
//                        }
//                        ioBuffer.getUnsigned();
//                    }
//                }
//            }
            return true;// 准备接收下一个包
        }
        return false;// 断包，或者执行完，
    }
}
